package com.hare.system_server.serice.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hare.auth.utils.SecurityUtils;
import com.hare.common.exception.ServiceException;
import com.hare.common.global.constant.BaseConstant;
import com.hare.common.utils.AssertUtils;
import com.hare.common.utils.BeanUtils;
import com.hare.common.utils.PageUtils;
import com.hare.system_api.dto.SysRoleDTO;
import com.hare.system_api.dto.SysUserDTO;
import com.hare.system_api.po.SysAdmin;
import com.hare.system_api.po.SysAdminRole;
import com.hare.system_api.vo.SysRoleVO;
import com.hare.system_api.vo.SysUserSystemVO;
import com.hare.system_server.mapper.SysRoleMapper;
import com.hare.system_server.mapper.SysUserMapper;
import com.hare.system_server.serice.SysAdminRoleService;
import com.hare.system_server.serice.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: Hare
 * @description: 用户实现service
 * @author: Hare
 * @create: 2022-11-21 16:52
 * @Version 6.0.1
 **/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysAdmin> implements SysUserService {

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysRoleMapper sysRoleMapper;

    @Autowired
    SysAdminRoleService sysAdminRoleService;


    /**
     * 用户管理==> 获取用户信息
     *
     * @param dto
     * @return
     */
    @Override
    public PageUtils<SysUserSystemVO> pageUserInfo(SysUserDTO dto) {
        QueryWrapper<SysAdmin> queryWrapper = new QueryWrapper<SysAdmin>();
        queryWrapper.lambda().like(StrUtil.isNotEmpty(dto.getUserName()), SysAdmin::getUserName, dto.getUserName())
                .eq(dto.getStatus() != null && dto.getStatus() != -1, SysAdmin::getStatus, dto.getStatus());
        IPage<SysAdmin> page = sysUserMapper.selectPage(new Page<>(dto.getPageIndex(), dto.getPageSize()), queryWrapper);

        List<SysUserSystemVO> list = page.getRecords().stream().map(t -> {
            SysUserSystemVO sysUserSystemVO = new SysUserSystemVO();
            sysUserSystemVO.setUserName(t.getUserName()).setAvatar(t.getAvatar())
                    .setCreateTime(t.getCreateTime())
                    .setNikeName(t.getNikeName())
                    .setSex(t.getSex()).setStatus(t.getStatus()).setId(t.getId()).setLoginIp(t.getLoginIp())
                    .setPhone(t.getPhone()).setEmail(t.getEmail());
            return sysUserSystemVO;
        }).collect(Collectors.toList());
        return new PageUtils<>(list, page.getTotal(), page.getSize(), page.getCurrent());
    }


    /**
     * 通过用户ID查询用户
     *
     * @param userId 用户ID
     * @return 用户对象信息
     */
    @Override
    public SysUserSystemVO selectUserById(String userId) {
        return sysUserMapper.selectUserById(userId);
    }

    /**
     * 用户管理==> 添加 or修改用户信息
     *
     * @param dto
     */
    @Override
    @Transactional
    public int userInsertOrEdit(SysUserDTO dto) {
        int rows = 0;
        if (dto.isInsert()) {
            // 新增
            AssertUtils.isNull(dto.getUserName(), "用户名不能为空");
            AssertUtils.isNull(dto.getNikeName(), "昵称不能为空");
            AssertUtils.isNull(dto.getEmail(), "邮箱不能为空");
            int userInfoCount = sysUserMapper.checkUserNameUnique(dto.getUserName());
            AssertUtils.isTrue(userInfoCount > 0, "新增 " + dto.getUserName() + " 用户名重复");
            int emailInfoCount = sysUserMapper.checkUserNameUnique(dto.getEmail());
            AssertUtils.isTrue(emailInfoCount > 0, "新增 " + dto.getEmail() + " 邮箱重复");
            SysAdmin sysAdmin = new SysAdmin();
            BeanUtils.copyProperties(dto, sysAdmin);
            // 初始密码
            sysAdmin.setPassword(SecurityUtils.encryptPassword(BaseConstant.PASS_WORD));
            // 添加用户信息
            rows = sysUserMapper.insert(sysAdmin);
            // 添加角色
            if (CollectionUtil.isNotEmpty(dto.getRoleIds())) {
                saveRoleAndAdmin(dto, sysAdmin.getId());
            }
            return rows;
        } else {
            // 修改
            this.checkUserAllowed(dto);
            SysAdmin sysAdmin = new SysAdmin();
            BeanUtils.copyPropertiesCancelIgnore(dto, sysAdmin);
            rows = sysUserMapper.updateById(sysAdmin);
            saveRoleAndAdmin(dto, sysAdmin.getId());
            return rows;
        }
    }


    /**
     * 添加 && 修改用户角色关联表
     *
     * @param dto    用户信息
     * @param userId 用户ID
     * @return
     */
    public void saveRoleAndAdmin(SysUserDTO dto, String userId) {
        List<SysAdminRole> roles = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(dto.getRoleIds())) {
            List<String> roleIds = dto.getRoleIds();
            roleIds.forEach(item -> {
                SysAdminRole sysAdminRole = new SysAdminRole();
                sysAdminRole.setAdminId(userId);
                sysAdminRole.setRoleId(item);
                roles.add(sysAdminRole);
            });
        }
        if (dto.isInsert()) {
            sysAdminRoleService.saveBatch(roles);
        } else {
            // 删除关联角色
            QueryWrapper<SysAdminRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(StrUtil.isNotEmpty(userId), SysAdminRole::getAdminId, userId);
            sysAdminRoleService.remove(queryWrapper);
            // 添加关联角色
            if (CollectionUtil.isNotEmpty(dto.getRoleIds())) {
                sysAdminRoleService.saveBatch(roles);
            }
        }
    }


    /**
     * 检查用户名是否唯一
     *
     * @param userName 用户名
     * @return
     */
    @Override
    public int checkUserNameUnique(String userName) {
        return sysUserMapper.checkUserNameUnique(userName);
    }


    /**
     * 检查邮箱是否唯一
     *
     * @param email 邮箱
     * @return
     */
    @Override
    public int checkEmailUnique(String email) {
        return sysUserMapper.checkUserNameUnique(email);
    }


    /**
     * 修改密码
     *
     * @param pas 密码
     * @param id  用户Id
     * @return
     */
    @Override
    public int updatePassWord(String pas, String id) {
        SysUserDTO dto = new SysUserDTO();
        dto.setId(id);
        this.checkUserAllowed(dto);
        String password = SecurityUtils.encryptPassword(pas);
        return sysUserMapper.updatePassWord(password, id);
    }


    /**
     * 用户管理==> 根据用户id查询用户信息
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public SysUserSystemVO selectUser(String userId) {
        SysUserSystemVO sysUserSystemVO = new SysUserSystemVO();
        if (StrUtil.isNotEmpty(userId)) {
            SysAdmin sysAdmin = new SysAdmin();
            sysAdmin.setId(userId);
            SysAdmin sysAdminInfo = sysUserMapper.selectById(sysAdmin);
            BeanUtils.copyPropertiesCancelIgnore(sysAdminInfo, sysUserSystemVO);
            SysUserSystemVO sysUserInfo = this.selectUserById(userId);
            List<String> roleIds = sysUserInfo.getRoles().stream().map(SysRoleVO::getId).collect(Collectors.toList());
            sysUserSystemVO.setRoleIds(roleIds);
        }

        List<SysRoleVO> sysRoleList = sysRoleMapper.roleInfoQuery(new SysRoleDTO());
        if (SecurityUtils.isAdmin(userId)) {
            sysUserSystemVO.setRoles(sysRoleList);
        } else {
            sysUserSystemVO.setRoles(sysRoleList.stream().filter(t -> !SecurityUtils.isAdminRole(t.getId())).collect(Collectors.toList()));
        }
        return sysUserSystemVO;
    }


    /**
     * 用户管理==> 根据用户id删除用户信息
     *
     * @param dto 用户信息
     * @return
     */
    @Override
    @Transactional
    public int delUserInfo(SysUserDTO dto) {
        QueryWrapper<SysAdminRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StrUtil.isNotEmpty(dto.getId()), SysAdminRole::getAdminId, dto.getId());
        sysAdminRoleService.remove(queryWrapper);
        return sysUserMapper.deleteById(dto.getId());
    }


    /**
     * 用户管理==> 根据用户id修改用户状态
     *
     * @param dto 用户信息
     * @return
     */
    @Override
    public int editUserStatus(SysUserDTO dto) {
        SysAdmin sysAdmin = new SysAdmin();
        sysAdmin.setId(dto.getId());
        sysAdmin.setStatus(dto.getStatus());
        return sysUserMapper.updateById(sysAdmin);
    }

    /**
     * 校验用户是否允许操作
     *
     * @param user 用户信息
     */
    @Override
    public void checkUserAllowed(SysUserDTO user) {
        if (StrUtil.isNotEmpty(user.getId()) && SecurityUtils.isAdmin(user.getId())) {
            throw new ServiceException("不允许操作超级管理员用户");
        }
    }
}
